package com.xscha.soyue.common.core.config.configure;

import com.fasterxml.jackson.databind.Module;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.xscha.soyue.common.core.json.BeanJsonService;
import com.xscha.soyue.common.core.json.JacksonBeanJsonService;
import com.xscha.soyue.common.core.json.SoyJackson2ObjectMapperBuilderCustomizer;
import com.xscha.soyue.common.core.json.module.JavaTimeModule;
import com.xscha.soyue.common.core.json.module.SoyStatusCodeModule;
import com.xscha.soyue.common.core.mapper.BeanMapperProvider;
import com.xscha.soyue.common.core.mapper.BeanMapperService;
import com.xscha.soyue.common.core.mapper.OrikaBeanMapperService;
import com.xscha.soyue.common.core.mapper.converter.SoyStatusCodeConverter;
import com.xscha.soyue.common.core.utils.BeanMapperUtils;
import com.xscha.soyue.common.core.utils.JsonUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.config.MethodInvokingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.List;

/**
 * MapperConfiguration
 *
 * @author Vondser
 * @version V2024.1.0
 */
@Slf4j
@Configuration
@RequiredArgsConstructor
public class MapperConfiguration {

	@Bean
	public SoyStatusCodeConverter soyStatusCodeConverter() {
		return new SoyStatusCodeConverter();
	}

	@Bean
	@ConditionalOnMissingBean(BeanMapperService.class)
	public BeanMapperService beanMapperService(List<BeanMapperProvider> providers) {
		log.info("初始化OrikaBeanMapperService...");
		return new OrikaBeanMapperService(providers);
	}

	@Bean
	public MethodInvokingBean callBeanMapperUtils(BeanMapperService beanMapperService) {
		MethodInvokingBean invoker = new MethodInvokingBean();
		invoker.setTargetClass(BeanMapperUtils.class);
		invoker.setTargetMethod("setBeanMapperService");
		invoker.setArguments(beanMapperService);
		return invoker;
	}
	/* ================json=================== */

	@Bean
	public SoyStatusCodeModule soyStatusCodeModule() {
		log.info("初始化SoyStatusCodeModule...");
		return new SoyStatusCodeModule();
	}

	@Bean
	public JavaTimeModule javaTimeModule() {
		log.info("初始化JavaTimeModule...");
		return new JavaTimeModule();
	}

	@Bean
	@ConditionalOnMissingBean(BeanJsonService.class)
	public BeanJsonService beanJsonService(ObjectMapper objectMapper) {
		log.info("初始化JacksonBeanJsonService...");
		return new JacksonBeanJsonService(objectMapper);
	}

	@Bean
	public SoyJackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer(List<Module> modules) {
		SoyJackson2ObjectMapperBuilderCustomizer customizer = new SoyJackson2ObjectMapperBuilderCustomizer();
		customizer.setModules(modules);
		return customizer;
	}

	@Bean
	public MethodInvokingBean callJsonUtils(BeanJsonService beanJsonService) {
		MethodInvokingBean invoker = new MethodInvokingBean();
		invoker.setTargetClass(JsonUtils.class);
		invoker.setTargetMethod("setBeanJsonService");
		invoker.setArguments(beanJsonService);
		return invoker;
	}
}
